package com.personal.core.utils;

import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.JSONUtils;

/**
 * JsonUtil
 * @author cuibo
 *
 */
public class JsonUtil
{
    private static Map<Class<?>, JsonConfig> configMap = new HashMap<Class<?>, JsonConfig>();

    public static void registValueProcessor(Class<?> objClazz, Class<?> valueClass, JsonValueProcessor processor)
    {
        JsonConfig config = (JsonConfig) configMap.get(objClazz);
        if (config == null)
        {
            config = new JsonConfig();
            configMap.put(objClazz, config);
        }

        config.registerJsonValueProcessor(valueClass, processor);
    }

    private static JsonConfig getConfig(Class<?> objClazz)
    {
        JsonConfig config = (JsonConfig) configMap.get(objClazz);

        if (config == null)
        {
            config = new JsonConfig();
            configMap.put(objClazz, config);
        }

        return config;
    }

    public static String toJson(Object value)
    {
        JSON json = buildJson(value);
        return json == null ? "" : json.toString();
    }

    public static JSON toJsonObject(String jsonStr)
    {
        return JSONSerializer.toJSON(jsonStr, new JsonConfig());
    }

    public static JSON toJsonObject(String jsonStr, JsonConfig jsonConfig)
    {
        return JSONSerializer.toJSON(jsonStr, jsonConfig);
    }

    public static Object toObject(String jsonStr, Class<?> targetClass)
    {
        JsonConfig config = getConfig(targetClass);
        if (config != null)
        {
            config.setRootClass(targetClass);
        }
        JSON json = toJsonObject(jsonStr, config);

        if (json == null)
        {
            return null;
        }
        if (json.isArray())
        {
            return JSONArray.toArray((JSONArray) json, config);
        }
        return JSONObject.toBean((JSONObject) json, config);
    }

    public static Object toObject(String jsonStr, JsonConfig config)
    {
        JSON json = toJsonObject(jsonStr, config);
        if (json == null)
        {
            return null;
        }
        if (json.isArray())
        {
            return JSONArray.toArray((JSONArray) json, config);
        }
        return JSONObject.toBean((JSONObject) json, config);
    }

    private static JSON buildJson(Object value)
    {
        if (value == null)
        {
            return null;
        }

        JsonConfig config = getConfig(value.getClass());

        if (isArray(value))
        {
            return JSONArray.fromObject(value, config);
        }
        return JSONObject.fromObject(value, config);
    }

    private static boolean isArray(Object value)
    {
        if ((value instanceof Enum))
        {
            return true;
        }
        if (JSONUtils.isArray(value))
        {
            return true;
        }
        return false;
    }
}
